package com.spzx.cart.service.impl;

import com.spzx.product.api.RemoteProductService;
import com.spzx.api.domain.CartInfo;
import com.spzx.cart.service.CartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.security.utils.SecurityUtils;
import com.spzx.product.domain.ProductSkuVo;
import io.jsonwebtoken.lang.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RemoteProductService remoteProductService;

    private String getCartKey(Long userId){
        return "user:cart:"+userId;
    }
    @Override
    public void addToCart(Long skuId, Integer skuNum) {
        //获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        //获取用户购物车的key
        String cartKey = getCartKey(userId);
        //构建hash集合操作
        BoundHashOperations<String,String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        String hashKey = skuId.toString();
        Integer threshold = 99;
        //判断当前商品是否在购物车中
        if(hashOps.hasKey(hashKey)){
            //从hash中获取用户购物车中的商品信息
            CartInfo cartInfo = hashOps.get(hashKey);
            //添加商品数量,但是商品的数量不能超过99
            int totalCount = cartInfo.getSkuNum() + skuNum;
            cartInfo.setSkuNum(totalCount>threshold?threshold:totalCount);
            hashOps.put(hashKey,cartInfo);
        }else {
            //判断购物车里的总商品种类不能超过50种
            Long size = hashOps.size();
            if(++size>50){
                throw new RuntimeException("购物车商品种类不能超过50");
            }
            //购物车中没有商品就需要添加商品
            CartInfo cartInfo = new CartInfo();
            cartInfo.setUserId(userId);
            cartInfo.setSkuNum(skuNum>threshold?threshold:skuNum);
            //远程调用获取商品的sku信息
            R<ProductSkuVo> productSkuResult = remoteProductService.getProductSku(skuId, SecurityConstants.INNER);
            //判断远程调用是否成功,如果失败就抛出异常
            if(R.FAIL==productSkuResult.getCode()){
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSkuVo productSkuVo = productSkuResult.getData();
            cartInfo.setSkuId(skuId);
            cartInfo.setSkuName(productSkuVo.getSkuName());
            cartInfo.setThumbImg(productSkuVo.getThumbImg());
            cartInfo.setCartPrice(productSkuVo.getSalePrice());
            cartInfo.setSkuPrice(productSkuVo.getSalePrice());
            cartInfo.setCreateTime(new Date());
            hashOps.put(hashKey,cartInfo);
        }
    }

    @Override
    public List<CartInfo> getCartList() {
        //获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        //获取redis中用户存储信息的key
        String cartKey = getCartKey(userId);
        List<CartInfo> cartInfos = redisTemplate.opsForHash().values(cartKey);
        //判断用户购物车是否为空
        if(!Collections.isEmpty(cartInfos)){
            List<CartInfo> collect = cartInfos
                    .stream()
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());
            return collect;
        }
        return null;
    }

    @Override
    public void deleteCart(Long skuId) {
        //获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        //获取redis中用户存储的购物车商品信息的key
        String cartKey = getCartKey(userId);
        //获取redis中缓存购物车商品信息的对象
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        hashOps.delete(skuId.toString());
    }

    @Override
    public void checkCartStatus(Long skuId, Integer isChecked) {
        //获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        //获取redis中用户存储的购物车商品信息的key
        String cartKey = getCartKey(userId);
        //获取操作购物车的hash对象
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //判断用户购物车中有没有这个商品
        if(hashOps.hasKey(skuId.toString())){
            CartInfo cartInfo = hashOps.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            //更新缓存
            hashOps.put(skuId.toString(),cartInfo);
        }
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        //获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        //获取redis中用户存储的购物车商品信息的key
        String cartKey = getCartKey(userId);
        //获取操作购物车的hash对象
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //获取用户购物车中的所有商品
        List<CartInfo> cartInfoList = hashOps.values();
        //为所有的商品同一修改状态
        cartInfoList.forEach(cartInfo->{
            CartInfo cart = hashOps.get(cartInfo.getSkuId().toString());
            cart.setIsChecked(isChecked);
            //更新缓存
            hashOps.put(cart.getSkuId().toString(),cart);
        });

    }

    @Override
    public void clearCart() {
        //获取当前登录用户的id
        Long userId = SecurityUtils.getUserId();
        //获取redis中用户购物车的key
        String cartKey = getCartKey(userId);
//        redisTemplate.delete(cartKey);
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        List<CartInfo> cartInfoList = hashOps.values();
        cartInfoList.forEach(cartInfo -> {
            hashOps.delete(cartInfo.getSkuId().toString());
        });
    }
}
